package controllers

import (
	"encoding/base64"
	"fmt"
	"github.com/astaxie/beego"
	"github.com/astaxie/beego/httplib"
	"github.com/fernet/fernet-go"
	"strconv"
	"time"
)

type Category struct {
	Id       int
	Name     string
	Level    int
	FatherId int
}

// type ErrorMessage struct {
// 	Status  int    //HTTP状态码
// 	Message string //返回信息
// }

type CategoryController struct {
	beego.Controller
}

func (this *CategoryController) Get() {
	var appKey = "myapp000001"
	//私匙
	var secretKey []*fernet.Key
	//解码私匙
	secret, err := fernet.DecodeKeys("cw_0x689RpI-jtRR7oE8h_eQsKImvJapLeSbXpwF4e4=")
	if err != nil {
		secretKey = nil
	} else {
		secretKey = secret
	}

	//请求头验证信息
	var headerAuthorization = fmt.Sprintf("%v:%v", appKey, strconv.FormatInt(time.Now().UnixNano(), 10))
	//GET请求
	req := httplib.Get("http://127.0.0.1:9090/v1/category")
	//设置Header验证信息
	req.Header("Authorization", headerAuthorization)
	//返回服务器base64加密令牌
	serverBase64Token, err := req.String()
	if err != nil {
		this.Ctx.Output.Body([]byte("服务器内部错误"))
	} else {
		//base64解码令牌
		toket, err := base64.StdEncoding.DecodeString(serverBase64Token)
		if err != nil {
			this.Ctx.Output.Body([]byte("服务器内部错误"))
		} else {
			if secretKey != nil {
				//解密获得的服务器端随机码
				signData := fernet.VerifyAndDecrypt(toket, 60*time.Second, secretKey)
				if signData != nil {
					//准备需要加密的数据
					StringToSign := []byte(fmt.Sprintf("%v:%v", string(signData), headerAuthorization))
					//加密得到令牌
					toket, err := fernet.EncryptAndSign(StringToSign, secretKey[0])
					if err != nil {
						this.Ctx.Output.Body([]byte("服务器内部错误"))
					} else {
						//令牌base64编码
						base64ToketStr := base64.StdEncoding.EncodeToString(toket)
						//再发GET请求,设置Header验证信息
						req := httplib.Get("http://127.0.0.1:9090/v1/category").Header("Authorization", base64ToketStr)
						//服务器端响应
						resp, err := req.Response()
						if err == nil {
							statusCode := resp.StatusCode
							fmt.Println("statusCode: ", statusCode)
							if statusCode == 200 {
								category := Category{}
								req.ToJson(&category)
								s, _ := req.String()
								fmt.Println("category: ", s)
								this.Data["json"] = category
								this.TplNames = "index.tpl"
							} else {
								this.Ctx.Output.Body([]byte("服务器内部错误"))
							}
						} else {
							this.Ctx.Output.Body([]byte("服务器内部错误"))
						}
					}
				} else {
					this.Ctx.Output.Body([]byte("未知服务器错误"))
				}
			} else {
				this.Ctx.Output.Body([]byte("服务器内部错误"))
			}
		}

	}
}
